/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

/*! @file OSGi/PImpl.inl
    @brief Class OSGi::PImpl inline methods.
    @author @ref Guillaume_Terrissol
    @date 29th December 2007 - 26th May 2013
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

#include <utility>

namespace OSGi
{
//------------------------------------------------------------------------------
//                           Constructors & Destructor
//------------------------------------------------------------------------------

    /*! @param pArgs Parameters passed to TPrivate best overload constructor
     */
    template<class TPrivate>
    template<class... TTs>
    PImpl<TPrivate>::PImpl(TTs&&... pArgs)
        : mData(new TPrivate(std::forward<TTs>(pArgs)...))
    { }


    /*! RAII rules.
     */
    template<class TPrivate>
    PImpl<TPrivate>::~PImpl() = default;


//------------------------------------------------------------------------------
//                                  Permutation
//------------------------------------------------------------------------------

    /*! Swaps the held pointer with that of another instance.
        @param pPImpl P-Impl to swap pointers with
     */
    template<class TPrivate>
    void PImpl<TPrivate>::swap(PImpl& pPImpl)
    {
        mData.swap(pPImpl.mData);
    }


//------------------------------------------------------------------------------
//                                    Access
//------------------------------------------------------------------------------

    /*! @return The held pointer
     */
    template<class TPrivate>
    TPrivate* PImpl<TPrivate>::operator->() const
    {
        return mData.get();
    }


    /*! @return A reference to the held instance
     */
    template<class TPrivate>
    TPrivate& PImpl<TPrivate>::operator*() const
    {
        return *mData;
    }
}
